package org.FaPe3D.core.parsers
{
	import flash.events.*;
	import flash.utils.*;
	
	import org.FaPe3D.*;
	import org.FaPe3D.core.events.*;
	import org.FaPe3D.core.parsers.casting.*;
	import org.FaPe3D.utils.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.view.*;
	
	public class ViewPort extends EventManager
	{
		private var _dic:Dictionary;
		private var _id:String;
		private var _count:int = 0;
		private var _elements:Elements;
		private var _test:Array = new Array()
		
		public function ViewPort(id:String)
		{
			_dic = new Dictionary(true);
			_id = id;
			_elements = new Elements();
		}
		
		public function getDictionary():Dictionary
		{
			return _dic; 
		}
		
		public function getPropertys(xml:XMLList):Object
		{
			var objs:Object = new Object();
			var objP:Object = new Object()
			var obj:Object = new Object();
			for(var i:uint = 0; i< xml.children().length(); i++)
			{
				if((xml.children()[i].@param+'').toLowerCase() == 'true')
				{
					objP[xml.children()[i].name().toString()] = Common.cast(xml.children()[i].@type, xml.children()[i].text());
				}else
				{
					obj[xml.children()[i].name().toString()] = Common.cast(xml.children()[i].@type, xml.children()[i].text());
				}
			}
			objs.propertys = obj;
			objs.params = objP;
			return objs;
		}
		
		public function getEvents(xml:XMLList):Object
		{
			var obj:Object = new Object();
			for(var i:uint = 0; i< xml.children().length(); i++)
			{
				obj[ xml.item[i].@id + '' ] = {
											type       : xml.children()[i].@type +''  ,
											'function' : {
															name : xml.children()[i]['function'].@name + '',
															arguments : getEventFunctionArguments(xml.children()[i]['function'].arguments.item)
														  }
											 };
			}
			return obj;
		}
		private function getEventFunctionArguments(xml:XMLList):Array
		{
			var arr:Array = new Array();
			
			for(var i in xml)
			{
				arr.push(
						Common.cast(xml[i].@type, xml[i].text())
						);
			}
			
			return arr;
		}
		
		public function getMaterials(xml:XMLList, _interactive:Boolean):Object
		{
			var obj:Object = new Object();
			var objs:Object = new Object();
			var objP:Object = new Object();
			for(var i:uint = 0; i< xml.item.length(); i++)
			{
				obj[ xml.item[i].@id + '' ] = {
											id     : xml.item[i].@id +'' ,
											type     : xml.item[i].@type +'' ,
											name     : xml.item[i].@name +'' ,
											property : getPropertys(new XMLList( xml.item[i].property )).propertys ,
											events : getEvents(new XMLList( xml.item[i].events ))
											 };
				obj[ xml.item[i].@id + '' ].property.interactive = _interactive;		 
				objP[ xml.item[i].@id + '' ]=  getPropertys(new XMLList( xml.item[i].property )).params	 
			}
			
			objs.materials = obj;
			objs.params = objP;
			
			return objs;
		}
		
		public function parse(xml:XML, parent:*):void
		{
			var item:Object = new Object();
			var params:Object = new Object();
			var matParams:Object = new Object();
			var propertys:Object = new Object();
			var events:Object = new Object();
			var materials:Object = new Object();
			var matEvents:Object = new Object();
			var returnValue:*;
			var ids:String;
			var interactive:Boolean = false;
			
			switch(xml.name().toString())
			{
				case 'viewport' :
					
					item.id   = (parent != null ? parent +'.' : '' ) + xml.item.@id + '';
					item.type = xml.item.@type + '';
					propertys = getPropertys(xml.item.property).propertys;
					params = getPropertys(xml.item.property).params;
					events = getEvents(xml.item.events);
					returnValue = _elements.cast(item.type, propertys, events, null, params);
					
					
					RegisterEvents.register(_id, returnValue, events);
					
					Adapter.getAdapter(_id).viewports.setViewports(item.id, returnValue);
					// Adapter.getAdapter(_id).viewports.setViewports('viewport.' + item.id, returnValue);
					
					if(xml.item.elements.children().length())
					{
						for(var i in xml.item.elements.children())
						{
							parse( new XML(xml.item.elements.children()[i]), null);
						}	
					}		
					
				break;
				
				case 'scences' :
				
					for(var s in xml.children())
					{
						item.id   = (parent != null ? parent +'.' : '' ) + xml.children()[s].@id + '';
						item.type = xml.children()[s].@type + '';
						item.default = ((xml.children()[s].@default + '').toLowerCase() == 'true' ? true : false);
						propertys = getPropertys(xml.children()[s].property).propertys;
						params = getPropertys(xml.children()[s].property).params;
						events = getEvents(xml.children()[s].events);
						returnValue = _elements.cast(item.type, propertys, events, null, params);
						RegisterEvents.register(_id, returnValue, events);
						
						Adapter.getAdapter(_id).scene.setScenes(item.id, returnValue, item.default);
//						Adapter.getAdapter(_id).scene.setScenes('scences.' + item.id, returnValue);
						
						if(xml.children()[s].elements.children().length())
						{
							for(var el:uint=0; el<xml.children()[s].elements.item.length(); el++)
							{
								_count++;
								setTimeout( 
									parse                                                               ,
								    Adapter.getAdapter(_id).settings.setting['property.delay'] * (el+1) ,
						 		    new XML(''+ xml.children()[s].elements.children()[el])              ,
						 		    item.id
						 		   );
							}
						}
					}
				
				break;
				
				case 'cameras' :
					
					for(var j in xml.children())
					{
						item.id   = xml.children()[j].@id + '';
						item.type = xml.children()[j].@type + '';
						item.default =((xml.children()[j].@default+'').toLowerCase() == 'true' ? true : false);
						propertys = getPropertys(xml.children()[j].property).propertys;
						params = getPropertys(xml.children()[j].property).params;
						events = getEvents(xml.children()[j].events);
						returnValue = _elements.cast(item.type, propertys, events, null, params);
						RegisterEvents.register(_id, returnValue, events);
						
						Adapter.getAdapter(_id).cameras.setCameras(item.id, returnValue, item.default );
//						Adapter.getAdapter(_id).cameras.setCameras('cameras.' + item.id, returnValue);
					}
					
				break;
				
				
				case 'item' :
					
					item.id   = (parent != null ? parent +'.' : '' ) + xml.@id + '';
					item.type = xml.@type + '';
					item.default = xml.@default + '';
					//
					propertys = getPropertys( new XMLList(xml.property) ).propertys
					params = getPropertys( new XMLList(xml.property) ).params
					events = getEvents( new XMLList(xml.events));
					//
					for(var t in events)
					{
						interactive = true;
						break;
					}
					//			
					materials = getMaterials( new XMLList(xml.materials) , interactive ).materials;
					matParams = getMaterials( new XMLList(xml.materials) , interactive ).params;
					returnValue =  _elements.cast(item.type, propertys, events, materials, params, matParams, _id);
					returnValue.name = item.id;
					// register all object listeners
					RegisterEvents.register(_id, returnValue, events);
					
					if(Adapter.getAdapter(_id).scene.getScenes(parent) != null)
					{
						Adapter.getAdapter(_id).scene.getScenes(parent).addChild(returnValue);
					}
							
					Adapter.getAdapter(_id).scene.setScenes(item.id, returnValue)
									
					if(xml.elements.item.length())
					{
						for(var el2:uint=0; el2<xml.elements.item.length(); el2++)
						{
							_count++;
							setTimeout( 
								parse                                                                ,
							    Adapter.getAdapter(_id).settings.setting['property.delay'] * (el2+1) ,
					 		    new XML(''+ xml.elements.item[el2])                                  ,
					 		    item.id
					 		 		  );
						}
					}
					//
					_count--;
					if(!_count)
					{
						dispatchEvent(new Event(Event.COMPLETE));
					}

				break;
			}	
			
		}
	}
}